package com.poetize.plus.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.poetize.plus.properties.SecurityProperties;
import com.poetize.plus.utils.JwtUtil;
import com.poetize.plus.utils.R;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

/**
 *
 * security登录成功处理器
 *
 * @author zuosy
 * @created 2024/3/28 15:53
 */
@Component
@RequiredArgsConstructor
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    private final JwtUtil jwtUtil;

    private final RedisTemplate<String, Object> redisTemplate;

    private final SecurityProperties securityProperties;

    private final ObjectMapper objectMapper;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        User user = (User)authentication.getPrincipal();
        String token = genToken(user.getUsername());
        //返回信息
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream out = response.getOutputStream();
        R<String> ok = R.ok(token);
        out.write(objectMapper.writeValueAsString(ok).getBytes(StandardCharsets.UTF_8));
        out.flush();
        out.close();
    }

    /**
     * 存储token逻辑
     *
     * @param username
     * @return
     */
    public String genToken(String username){
        //签发token
        String token = jwtUtil.genAccessToken(username);
        //签发refresh_token
        String refreshToken = jwtUtil.genRefreshToken(username);
        //redis存储token
        redisTemplate.opsForValue().set(
                token,
                token,
                securityProperties.getJwt().getExpire(),
                TimeUnit.of(securityProperties.getJwt().getChronoUnit())
        );
        //redis存储refresh_token
        redisTemplate.opsForValue().set(
                "refresh_token:" + token,
                refreshToken,
                securityProperties.getJwt().getRefreshExpiration(),
                TimeUnit.of(securityProperties.getJwt().getChronoUnit())
        );
        return token;
    }
}
